{
  "nbformat_minor": 0,
  "nbformat": 4,
  "cells": [
    {
      "source": [
        "#### Copyright 2017 Google LLC."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "JndnmDMp66FL"
      }
    },
    {
      "source": [
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "hMqWDc_m6rUC",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        },
        "cellView": "both"
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " # Conceptos de programaci\u00f3n de TensorFlow"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "rFpcvnCJ4Xkf"
      }
    },
    {
      "source": [
        " **Objetivos de aprendizaje:**\n",
        "  * Obt\u00e9n informaci\u00f3n sobre los conceptos b\u00e1sicos del modelo de programaci\u00f3n de TensorFlow, enfocado en los siguientes conceptos:\n",
        "    * tensores\n",
        "    * operaciones\n",
        "    * gr\u00e1ficos\n",
        "    * sesiones\n",
        "  * Crea un programa simple de TensorFlow que genere un gr\u00e1fico predeterminado y una sesi\u00f3n que ejecute el gr\u00e1fico."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "9IkBOsrNzahz"
      }
    },
    {
      "source": [
        " **Nota:** Lee atentamente este instructivo. El modelo de programaci\u00f3n de TensorFlow probablemente sea diferente a otros que conozcas y, por lo tanto, tal vez no sea lo suficientemente intuitivo."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "YMG9mHPdzahz"
      }
    },
    {
      "source": [
        " ## Resumen de conceptos\n",
        "El nombre de TensorFlow proviene de **tensores**, que son matrices de dimensionalidad arbitraria. Con TensorFlow, puedes manipular tensores con una gran cantidad de dimensiones. No obstante, mayormente trabajar\u00e1s con uno o m\u00e1s de los siguientes tensores de baja dimensionalidad:\n",
        "  * Un **escalar** es una matriz de 0-d (un tensor en el orden 0). Por ejemplo, `\"Howdy\"` o `5`\n",
        "  * Un **vector** es una matriz de 1-d (un tensor en el orden 1). Por ejemplo, `[2, 3, 5, 7, 11]` o `[5]`\n",
        "  * Un **arreglo** es una matriz de 2-d (un tensor en el orden 2). Por ejemplo, `[[3.1, 8.2, 5.9][4.3, -2.7, 6.5]]`\n\n",
        "Las **operaciones** de TensorFlow crean, destruyen y manipulan tensores. La mayor\u00eda de las l\u00edneas de c\u00f3digo en un programa t\u00edpico de TensorFlow son operaciones.\n\n",
        "Un **gr\u00e1fico** de TensorFlow (tambi\u00e9n conocido como **gr\u00e1fico computacional** o **gr\u00e1fico de flujo de datos**) es, de hecho, una estructura de datos de gr\u00e1fico. Muchos programas de TensorFlow consisten en un solo gr\u00e1fico, pero es posible que los programas de TensorFlow alternativamente creen gr\u00e1ficos m\u00faltiples. Los nodos de un gr\u00e1fico son operaciones; los bordes de un gr\u00e1fico son tensores. Los tensores fluyen en el gr\u00e1fico, manipulado en cada nodo mediante una operaci\u00f3n. El tensor de resultado de una operaci\u00f3n por lo general se convierte en el tensor de entrada de una operaci\u00f3n subsiguiente. TensorFlow implementa un **modelo de ejecuci\u00f3n relajado**, lo que significa que los nodos solo se calculan cuando es necesario, en funci\u00f3n de los nodos asociados.\n\n",
        "Los tensores pueden almacenarse en el gr\u00e1fico como **constantes** o **variables**. Como podr\u00e1s imaginar, las constantes tienen tensores cuyos valores no pueden cambiar, mientras que las variables tienen tensores cuyos valores s\u00ed pueden cambiar. Sin embargo, lo que posiblemente no imagines es que las constantes y las variables son solo m\u00e1s operaciones en el gr\u00e1fico. Una constante es una operaci\u00f3n que siempre arroja el mismo valor de tensor. Una variable es una operaci\u00f3n que arrojar\u00e1 el tensor que tuviera asignado.\n\n",
        "Para definir una constante, usa el operador `tf.constant` y env\u00eda su valor. Por ejemplo:\n",
        "```\n",
        "  x = tf.constant([5.2])\n",
        "```\n",
        "De manera similar, puedes crear una variable como la siguiente:\n",
        "```\n",
        "  y = tf.Variable([5])\n",
        "```\n",
        "O bien puedes crear primero la variable y, luego, asignar un valor como el siguiente (ten en cuenta que siempre debes especificar un valor predeterminado):\n",
        "```\n",
        "  y = tf.Variable([0])\n",
        "  y = y.assign([5])\n",
        "```\n",
        "Una vez que hayas definido algunas constantes o variables, podr\u00e1s combinarlas con otras operaciones, como `tf.add`. Cuando eval\u00faas la operaci\u00f3n `tf.add`, esta invocar\u00e1 a tus operaciones `tf.constant` o `tf.Variable` para obtener sus valores y, luego, obtener un tensor nuevo con la suma de esos valores.\n\n",
        "Los gr\u00e1ficos deben ejecutarse dentro de una **sesi\u00f3n** de TensorFlow, que incluye el estado de los gr\u00e1ficos que ejecuta:\n",
        "```\n",
        "with tf.Session() as sess:\n",
        "  initialization = tf.global_variables_initializer()\n",
        "  print(y.eval())\n",
        "```\n",
        "Cuando trabajas con variables `tf.Variable`, debes inicializarlas de forma expl\u00edcita. Para hacerlo, debes invocar a `tf.global_variables_initializer` al inicio de la sesi\u00f3n, como se muestra arriba.\n\n",
        "**Nota:** Una sesi\u00f3n puede distribuir la ejecuci\u00f3n del gr\u00e1fico en varias m\u00e1quinas (si asumimos que el programa se ejecuta en un marco de trabajo de c\u00e1lculo distribuido). Para obtener m\u00e1s informaci\u00f3n, consulta [TensorFlow distribuido](https://www.tensorflow.org/deploy/distributed).\n",
        "### Resumen\n",
        "La programaci\u00f3n de TensorFlow b\u00e1sicamente es un proceso de dos pasos:\n",
        "1. Crea constantes, variables y operaciones en un gr\u00e1fico.\n",
        "2. Eval\u00faa esas constantes, variables y operaciones en una sesi\u00f3n.\n",
        ""
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "NzKsjX-ufyVY"
      }
    },
    {
      "source": [
        " ## Creaci\u00f3n de un programa simple de TensorFlow\n",
        "\n",
        "Veamos c\u00f3mo codificar un programa simple de TensorFlow que agrega dos constantes. "
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "VL0yWNNdgBpG"
      }
    },
    {
      "source": [
        " ### Establecimiento de sentencias de importaci\u00f3n\n",
        "\n",
        "Al igual que con casi todos los programas de Python, empezar\u00e1s especificando algunas sentencias de `import`.\n",
        "El conjunto de sentencias de `import` necesario para ejecutar un programa de TensorFlow depende, por supuesto, de las funciones que accede tu programa. Como m\u00ednimo, debes proporcionar la sentencia `import tensorflow` en todos los programas de TensorFlow:"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "mN4R0gmMzah3"
      }
    },
    {
      "source": [
        "import tensorflow as tf"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "SDbi6heigEGA",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " **No te olvides de ejecutar el bloque de c\u00f3digo previo (las sentencias de `import`).**\n",
        "\n",
        "Otras sentencias de importaci\u00f3n habituales incluyen lo siguiente:\n",
        "\n",
        "```\n",
        "  import matplotlib.pyplot as plt # Visualizaci\u00f3n del conjunto de datos\n",
        "  import numpy as np              # Biblioteca de Python num\u00e9rica de bajo nivel\n",
        "  import pandas as pd             # Biblioteca de Python num\u00e9rica de alto nivel\n",
        "```"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "6RRT4YIA4fQd"
      }
    },
    {
      "source": [
        " TensorFlow proporciona un **gr\u00e1fico predeterminado**. Sin embargo, recomendamos de forma expl\u00edcita crear tu propio `Graph` en lugar de proporcionar el estado de seguimiento (p. ej., es posible que quieras trabajar con un `Graph` diferente en cada celda)."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "1aNpvufRgbTD"
      }
    },
    {
      "source": [
        "from __future__ import print_function\n\n",
        "import tensorflow as tf\n",
        "\n",
        "# Create a graph.\n",
        "g = tf.Graph()\n",
        "\n",
        "# Establish the graph as the \"default\" graph.\n",
        "with g.as_default():\n",
        "  # Assemble a graph consisting of the following three operations:\n",
        "  #   * Two tf.constant operations to create the operands.\n",
        "  #   * One tf.add operation to add the two operands.\n",
        "  x = tf.constant(8, name=\"x_const\")\n",
        "  y = tf.constant(5, name=\"y_const\")\n",
        "  sum = tf.add(x, y, name=\"x_y_sum\")\n",
        "\n",
        "\n",
        "  # Now create a session.\n",
        "  # The session will run the default graph.\n",
        "  with tf.Session() as sess:\n",
        "    print(sum.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "Md8ze8e9geMi",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ## Ejercicio: Introduce un tercer operando\n",
        "\n",
        "Revisa la lista de c\u00f3digos de arriba para agregar tres n\u00fameros enteros, en lugar de dos:\n",
        "\n",
        "  1. Define una tercera constante escalar de n\u00fameros enteros, `z`, y as\u00edgnala a un valor de `4`.\n",
        "  2. Agrega `z` a `sum` para generar una nueva suma.\n",
        "  \n",
        "  **Sugerencia:** Consulta los documentos de la API para [tf.add()](https://www.tensorflow.org/api_docs/python/tf/add) para obtener m\u00e1s informaci\u00f3n sobre su firma de funci\u00f3n.\n",
        "  \n",
        "  3. Vuelve a ejecutar el bloque de c\u00f3digo modificado. \u00bfEl programa gener\u00f3 la suma total correcta?"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "7mSz5GVqggZy"
      }
    },
    {
      "source": [
        " ### Soluci\u00f3n\n",
        "\n",
        "Haz clic a continuaci\u00f3n para conocer la soluci\u00f3n."
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "Zep4W80H9awM"
      }
    },
    {
      "source": [
        "# Create a graph.\n",
        "g = tf.Graph()\n",
        "\n",
        "# Establish our graph as the \"default\" graph.\n",
        "with g.as_default():\n",
        "  # Assemble a graph consisting of three operations. \n",
        "  # (Creating a tensor is an operation.)\n",
        "  x = tf.constant(8, name=\"x_const\")\n",
        "  y = tf.constant(5, name=\"y_const\")\n",
        "  sum = tf.add(x, y, name=\"x_y_sum\")\n",
        "  \n",
        "  # Task 1: Define a third scalar integer constant z.\n",
        "  z = tf.constant(4, name=\"z_const\")\n",
        "  # Task 2: Add z to `sum` to yield a new sum.\n",
        "  new_sum = tf.add(sum, z, name=\"x_y_z_sum\")\n",
        "\n",
        "  # Now create a session.\n",
        "  # The session will run the default graph.\n",
        "  with tf.Session() as sess:\n",
        "    # Task 3: Ensure the program yields the correct grand total.\n",
        "    print(new_sum.eval())"
      ],
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "4OTZPqhS9kzu",
        "colab": {
          "autoexec": {
            "wait_interval": 0,
            "startup": false
          }
        }
      },
      "outputs": [],
      "execution_count": 0
    },
    {
      "source": [
        " ## M\u00e1s informaci\u00f3n\n",
        "\n",
        "Para explorar m\u00e1s los gr\u00e1ficos b\u00e1sicos de TensorFlow, prueba con el siguiente instructivo:\n",
        "\n",
        "  * [Mandelbrot set](https://www.tensorflow.org/tutorials/non-ml/mandelbrot)"
      ],
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "BrlnLTesgywL"
      }
    }
  ],
  "metadata": {
    "colab": {
      "default_view": {},
      "version": "0.3.2",
      "collapsed_sections": [
        "JndnmDMp66FL",
        "Zep4W80H9awM"
      ],
      "name": "tensorflow_programming_concepts.ipynb",
      "views": {}
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  }
}
